#include "Dri_Timer_2.h"
#include "Int_Buzzer.h"
#include "Dri_Grip.h"

/**
 * @brief 创建一个数组,用于存入指针函数
 *
 */
static Timer2_CALLBACK S_Timer2_CallBack_Array[MAX_CALLBACK_ARRAR];

// 数组已经使用总数
static u8 s_array_count = 0;

/**
 * 初始化定时器中断
 */
void Dri_Timer2_Init(void)
{
    // 1. 打开中断开关 ------------------------------ -----------------------
    // 1.1 打开中断总开关
    EA = 1;
    // 1.2 打开 Timer2 的中断开关
    ET2 = 1;

    // 2. 设置 Timer2 的脉冲来源和工作模式   ----------------------------------
    // 2.1 使用系统时钟，作为定时器
    C_T2 = 0;

    // 2.2 设置为16位自动重装载
    // 不作为串口的发送波特率发生器 TCLK=0时，定时器1作为串行口发送波特率发生器；当TCLK=1时，定时器2作为串行口发送波特率发生器
    RCLK = 0;
    TCLK = 0;
    // 使用重装载模式
    CP_RL2 = 0;

    // 2.3 关闭定时器2的外部使能
    EXEN2 = 0;

    // 3. 设置脉冲计数器的起始值  ------------------------------ ---------------
    // 因为晶振= 11059200 秒/hz, 我们选择是12T为一个机器时钟,设置1毫秒多少个机器时钟  --> 11059200 / 12X1000  ≈ 922
    // 因为是8位溢出以后,进行定时器触发所以 16bit 11111111 11111111 -> 10进制 65535,
    // 但是65536 才能溢出进行定时器触发 所以 但是(65536 - 922) = 64614 才是初始值,等到了但是65536就触发
    // 每一微秒需要的溢出率
    TL2 = 64614;
    // TH0 是高8位,所以把FC 给他
    TH2 = 64614 >> 8;
    // 溢出自动重装载数据
    RCAP2L = TL2;
    RCAP2H = TH2;

    // 5. 开始计数  ------------------------------ ------------------------------
    TR2 = 1;
}

/**
 * @brief 定时器中断服务程序
 *
 */
void Dri_Timer2_interrupt() interrupt 5
{
    u8 i;
    for (i = 0; i < s_array_count; i++) {
        S_Timer2_CallBack_Array[i]();
    }
    // 定时器2溢出标志。定时器2溢出时置位，必须由软件清除。
    TF2 = 0;
}

/**
 * @brief 添加回调函数
 *
 * @param callBack 回调函数
 * @return bit 添加成功 = 1, 失败 = 0
 */
bit Dri_Timer_AddCallBack(Timer2_CALLBACK callBack)
{
    u8 i;
    for (i = 0; i < s_array_count; i++) {
        // 存在则返回1
        // Timer2_CALLBACK one = S_Timer2_CallBack_Array[i];
        if (S_Timer2_CallBack_Array[i] == callBack) {
            return 1;
        }
    }

    // 不存在,则添加
    S_Timer2_CallBack_Array[s_array_count] = callBack;
    s_array_count++;
    return 1;
}

/**
 * @brief 删除回调函数
 *
 * @param callBack 回调函数
 * @return bit 删除成功 = 1, 删除失败 = 0
 */
bit Dri_Timer_DelCallBack(Timer2_CALLBACK callBack)
{
    // 标识是否存在元素
    bit tag = 0;
    u8 i;
    // 判断是否存在
    for (i = 0; i < s_array_count; i++) {
        if (tag) {
            S_Timer2_CallBack_Array[i - 1] = S_Timer2_CallBack_Array[i];
            continue;
        }

        if (S_Timer2_CallBack_Array[i] == callBack) {
            tag = 1;
            continue;
        }
    }

    // 删除成功
    if (tag == 1) {
        s_array_count--;
        return 1;
    }

    return 0;
}
